package com.ybear.ybcomponent.clicksub;

import android.util.SparseArray;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

/**
 * 点击订阅管理器
 */
public final class ClickSubManage implements ClickSubDao {
    private final SparseArray<List<View.OnClickListener>> mClickMap;
    private final SparseArray<List<View.OnLongClickListener>> mLongClickMap;

    private ClickSubManage() {
        mClickMap = new SparseArray<>();
        mLongClickMap = new SparseArray<>();
    }

    public static ClickSubManage get() { return HANDLER.I; }
    private static final class HANDLER {
        private static final ClickSubManage I = new ClickSubManage();
    }

    /**
     * 处理点击事件
     * @param v     处理的View
     */
    public void onClick(View v) {
        if( v == null ) return;
        enableClick( v );
        mClickMap.put( v.hashCode(), new ArrayList<>() );
        View.OnClickListener clickListener = view -> {
            if( !containsClick( v ) ) return;
            List<View.OnClickListener> list = mClickMap.get( v.hashCode() );
            if( list == null ) return;
            try {
                for( View.OnClickListener l : list ) {
                    if( l != null ) l.onClick( view );
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        };
        v.setOnClickListener( clickListener );
    }

    /**
     * 处理长按事件
     * @param v     处理的View
     * @param ret   长按的返回结果
     */
    public void onLongClick(View v, boolean ret) {
        if( v == null ) return;
        enableClick( v );
        mLongClickMap.put( v.hashCode(), new ArrayList<>() );

        View.OnLongClickListener clickListener = view -> {
            if( !containsLongClick( view ) ) return ret;
            List<View.OnLongClickListener> list = mLongClickMap.get( view.hashCode() );
            if( list == null ) return ret;
            try {
                for( View.OnLongClickListener l : list ) {
                    if( l != null ) l.onLongClick( view );
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return ret;
        };
        v.setOnLongClickListener( clickListener );
    }

    /**
     * 处理长按事件
     * @param v     处理的View
     */
    public void onLongClick(View v) { onLongClick( v, false ); }

    private void enableClick(View v) {
        v.setFocusable( true );
        v.setClickable( true );
    }

    /**
     * 点击监听器是否存在
     * @param v     处理事件的View
     * @param l     监听器
     * @return      是否存在
     */
    @Override
    public boolean containsClick(View v, View.OnClickListener l) {
        if( v == null || l == null ) return false;
        for( View.OnClickListener val : mClickMap.get( v.hashCode() ) ) {
            if( val != null && val.equals( l ) ) return true;
        }
        return false;
    }

    /**
     * 点击监听器是否存在
     * @param v     处理事件的View
     * @return      是否存在
     */
    @Override
    public boolean containsClick(View v) {
        return v != null && mClickMap.indexOfKey( v.hashCode() ) != -1;
    }

    /**
     * 点击监听器是否存在
     * @param l     监听器
     * @return      是否存在
     */
    @Override
    public boolean containsClick(View.OnClickListener l) {
        if( l == null ) return false;
        for (int i = 0; i < mClickMap.size(); i++) {
            for( View.OnClickListener val : mClickMap.valueAt( i ) ) {
                if( val != null && val.equals( l ) ) return true;
            }
        }
        return false;
    }

    /**
     * 添加点击事件监听器
     * @param l     监听器
     */
    @Override
    public void addOnClickListener(View v, View.OnClickListener l) {
        if( l == null || !containsClick( v ) ) return;
        List<View.OnClickListener> list = mClickMap.get( v.hashCode() );
        if( list == null ) list = new ArrayList<>();
        list.add( l );
        mClickMap.put( v.hashCode(), list );
    }

    /**
     * 移除点击事件监听器
     * @param v     处理事件的View
     * @param l     监听器
     */
    @Override
    public void removeOnClickListener(View v, View.OnClickListener l) {
        if( !containsClick( v ) || l == null ) return;
        mClickMap.get( v.hashCode() ).remove( l );
    }

    /**
     * 移除点击事件监听器
     * @param v     处理事件的View
     */
    @Override
    public void removeOnClickListener(View v) {
        if( v == null ) return;
        mClickMap.remove( v.hashCode() );
    }

    /**
     * 移除点击事件监听器
     * @param l     监听器
     */
    @Override
    public void removeOnClickListener(View.OnClickListener l) {
        if( l == null ) return;
        int removeKey = -1;
        for (int i = 0; i < mClickMap.size(); i++) {
            for( View.OnClickListener val : mClickMap.valueAt( i ) ) {
                if( val != null && val.equals( l ) ) {
                    removeKey = i;
                    break;
                }
            }
        }
        if( removeKey != -1 ) mClickMap.valueAt( removeKey ).remove( l );
    }

    /**
     * 长按监听器是否存在
     * @param v     处理事件的View
     * @param l     监听器
     * @return      是否存在
     */
    @Override
    public boolean containsLongClick(View v, View.OnLongClickListener l) {
        if( v == null || l == null ) return false;
        for( View.OnLongClickListener val : mLongClickMap.get( v.hashCode() ) ) {
            if( val != null && val.equals( l ) ) return true;
        }
        return false;
    }

    /**
     * 长按监听器是否存在
     * @param v     处理事件的View
     * @return      是否存在
     */
    @Override
    public boolean containsLongClick(View v) {
        return v != null && mLongClickMap.indexOfKey( v.hashCode() ) != -1;
    }

    /**
     * 长按监听器是否存在
     * @param l     监听器
     * @return      是否存在
     */
    @Override
    public boolean containsLongClick(View.OnLongClickListener l) {
        if( l == null ) return false;
        for (int i = 0; i < mLongClickMap.size(); i++) {
            for( View.OnLongClickListener val : mLongClickMap.valueAt( i ) ) {
                if( val != null && val.equals( l ) ) return true;
            }
        }
        return false;
    }

    /**
     * 添加长按事件监听器
     * @param v     处理事件的View
     * @param l     监听器
     */
    @Override
    public void addOnLongClickListener(View v, View.OnLongClickListener l) {
        if( !containsLongClick( v ) || l == null ) return;
        List<View.OnLongClickListener> list = mLongClickMap.get( v.hashCode() );
        if( list == null ) list = new ArrayList<>();
        list.add( l );
        mLongClickMap.put( v.hashCode(), list );
    }

    /**
     * 移除长按事件监听器
     * @param v     处理事件的View
     * @param l     监听器
     */
    @Override
    public void removeOnLongClickListener(View v, View.OnLongClickListener l) {
        if( l == null || !containsLongClick( v ) ) return;
        mLongClickMap.get( v.hashCode() ).remove( l );
    }

    /**
     * 移除长按事件监听器
     * @param v     处理事件的View
     */
    @Override
    public void removeOnLongClickListener(View v) {
        if( v == null ) return;
        mLongClickMap.remove( v.hashCode() );
    }

    /**
     * 移除长按事件监听器
     * @param l     监听器
     */
    @Override
    public void removeOnLongClickListener(View.OnLongClickListener l) {
        if( l == null ) return;
        int removeKey = -1;
        for (int i = 0; i < mLongClickMap.size(); i++) {
            for( View.OnLongClickListener val : mLongClickMap.valueAt( i ) ) {
                if( val != null && val.equals( l ) ) {
                    removeKey = i;
                    break;
                }
            }
        }
        if( removeKey != -1 ) mLongClickMap.valueAt( removeKey ).remove( l );
    }
}
